gdkcairo: Bail if surface is in error
authorBenjamin Otte <otte@redhat.com>
Fri, 20 Feb 2015 23:03:49 +0000 (00:03 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 25 Feb 2015 00:55:28 +0000 (01:55 +0100)
Don't try to paint onto an error surface. This happens for example when
gdk_cairo_set_source_pixbuf() is called with a pixbuf that is too big
for Cairo to handle.

Spotted by Christian Boxdörfer

gdk/gdkcairo.c
testsuite/gdk/Makefile.am
testsuite/gdk/cairo.c [new file with mode: 0644]

index bb7f33efd1c148730fadfc67ccb11d1af424a5f4..633b39153fcdf5c4bb00e29ffb9d86a31807a999 100644 (file)
@@ -185,6 +185,9 @@ gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
   int n_channels;
   int j;
 
+  if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+    return;
+
   /* This function can't just copy any pixbuf to any surface, be
    * sure to read the invariants here before calling it */
 
index 5b0d30f08677856b548f8f2cb2d7ec0d7872f366..32b018a0c312c4efbd3b3daeece6fb25651be24e 100644 (file)
@@ -18,10 +18,11 @@ LDADD =                             \
 #TEST_PROGS              += check-gdk-cairo
 
 TEST_PROGS +=                          \
-       rgba                            \
-       encoding                        \
+       cairo                           \
        display                         \
+       encoding                        \
        keysyms                         \
+       rgba                            \
        $(NULL)
 
 CLEANFILES =                   \
diff --git a/testsuite/gdk/cairo.c b/testsuite/gdk/cairo.c
new file mode 100644 (file)
index 0000000..77be879
--- /dev/null
@@ -0,0 +1,40 @@
+#include <gdk/gdk.h>
+
+static void
+test_set_source_big_pixbuf (void)
+{
+  cairo_surface_t *surface;
+  GdkPixbuf *pixbuf;
+  cairo_t *cr;
+
+#define WAY_TOO_BIG 65540
+
+  /* Check that too big really is to big.
+   * If this check fails, somebody improved Cairo and this test is useless.
+   */
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WAY_TOO_BIG, 1);
+  g_assert_cmpint (cairo_surface_status (surface), !=, CAIRO_STATUS_SUCCESS);
+  cairo_surface_destroy (surface);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
+  cr = cairo_create (surface);
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, WAY_TOO_BIG, 1);
+
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  g_assert_cmpint (cairo_status (cr), !=, CAIRO_STATUS_SUCCESS);
+
+  g_object_unref (pixbuf);
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  gdk_init (&argc, &argv);
+
+  g_test_add_func ("/drawing/set-source-big-pixbuf", test_set_source_big_pixbuf);
+
+  return g_test_run ();
+}